package com.xnyzc.lhy.common.component.payment;

import com.alibaba.fastjson.JSONObject;
import com.xnyzc.lhy.common.constant.PayConstant;
import com.xnyzc.lhy.common.util.RandomUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.UUID;

/**
 * @Description 微信支付
 * @Author 刘举
 * @Date 2019/8/7 11:19
 **/
@Slf4j
@Component
public class WeChatPay {

    private static String wxAppId;

    private static String wxAppSecret;

    private static String wxPartnerId;

    private static String apiDomain;

    @Value("${global.weChat.pay.appId}")
    public void setAppId(String appId) {
        wxAppId = appId;
    }

    @Value("${global.weChat.pay.appSecret}")
    public void setAppSecret(String appSecret) {
        wxAppSecret = appSecret;
    }

    @Value("${global.weChat.pay.partnerId}")
    public void setPartnerId(String partnerId) {
        wxPartnerId = partnerId;
    }

    @Value("${global.apiDomain}")
    public void setApiDomain(String domain) {
        apiDomain = domain;
    }


    /**
     * 调起微信支付接口
     *
     * @param orderNo
     * @param orderSubject
     * @param totalAmount
     * @param passBackJson
     * @return
     */
    public static Map<String, String> getWXPayParam(String orderNo, String orderSubject, String totalAmount, JSONObject passBackJson) {

        Map<String, String> wxMap = new HashMap<>(16);
        String notifyUrl = apiDomain + PayConstant.WX_NOTIFY_URL;
        // 费用处理
        totalAmount = String.valueOf((new BigDecimal(totalAmount).multiply(new BigDecimal(100))).intValue());
        Map<String, Object> map = WeChatPayUtil.requestParam(orderNo, orderSubject, totalAmount, notifyUrl, passBackJson);
        // 应用ID
        wxMap.put("appid", wxAppId);
        // 商户号
        wxMap.put("partnerid", wxPartnerId);
        // 预支付交易会话ID
        wxMap.put("prepayid", WeChatPayUtil.getWXPrepayID(map));
        // 扩展字段 暂填写固定值Sign=WXPay
        wxMap.put("package", "Sign=WXPay");
        // 随机字符串
        wxMap.put("noncestr", (UUID.randomUUID().toString()).replaceAll("-", ""));
        // 需要转换成秒(10位数字)
        wxMap.put("timestamp", String.valueOf((System.currentTimeMillis()) / 1000));
        // 签名
        wxMap.put("sign", WeChatPayUtil.getPaySign(wxMap));

        return wxMap;
    }

    /**
     * 退款函数，该方法可以对曾经部分退款的订单进行再次退款
     *
     * @param orderNo   商户订单号
     * @param totalFee  退款对应的订单的总金额（以“元”为单位）
     * @param refundFee 计划退款的金额（以“元”为单位）
     * @return
     */
    public static Boolean weChatRefund(String orderNo, double totalFee, double refundFee) {
        // 退款单号，随机生成 ，但长度应该跟文档一样（32位）(卖家信息校验不一致，请核实后再试)
        String outRefundNo = UUID.randomUUID().toString().substring(0, 32);

        String nonceStr = RandomUtil.getRandomAllCharStr(10);
        SortedMap<String, String> packageParams = new TreeMap<String, String>();
        packageParams.put("appid", wxAppId);
        // 微信公众平台文档：“微信支付”--》“商户信息”--》“商户号”，将该值赋值给partner
        packageParams.put("mch_id", wxPartnerId);
        // 随机字符串
        packageParams.put("nonce_str", nonceStr);
        packageParams.put("out_trade_no", orderNo);
        packageParams.put("out_refund_no", outRefundNo);
        // 订单的总金额,以分为单位（填错了貌似提示：同一个out_refund_no退款金额要一致）
        packageParams.put("total_fee", String.valueOf((int) (totalFee * 100)));
        // 退款金额，以分为单位（填错了貌似提示：同一个out_refund_no退款金额要一致）
        packageParams.put("refund_fee", String.valueOf((int) (refundFee * 100)));
        // 商户订单号MCHID
        packageParams.put("op_user_id", wxPartnerId);

        RequestHandler reqHandler = new RequestHandler(null, null);
        reqHandler.init(wxAppId, wxAppSecret, wxPartnerId);
        String sign = reqHandler.createSign(packageParams);
        String xml = "<xml>" +
                "<appid>" + wxAppId + "</appid>" +
                "<mch_id>" + wxPartnerId + "</mch_id>" +
                "<nonce_str>" + nonceStr + "</nonce_str>" +
                "<sign><![CDATA[" + sign + "]]></sign>" +
                "<out_trade_no>" + orderNo + "</out_trade_no>" +
                "<out_refund_no>" + outRefundNo + "</out_refund_no>" +
                "<total_fee>" + totalFee + "</total_fee>" +
                "<refund_fee>" + refundFee + "</refund_fee>" +
                "<op_user_id>" + wxPartnerId + "</op_user_id>" +
                "</xml>";
        String createOrderURL = "https://api.mch.weixin.qq.com/secapi/pay/refund";
        String refundResult = "";
        try {
            refundResult = ClientCustomSSL.doRefund(createOrderURL, xml);
        } catch (Exception e) {
        }
        log.info("微信退款返回结果：{}", refundResult);
        if (Objects.equals(refundResult, "") || refundResult.contains("err_code")) {
            return false;
        } else {
            return true;
        }
    }


}
